package handler

import (
	_ "encoding/json"
	"fmt"
	"net/http"
	_ "path/filepath"
	"strconv"
	_ "strings"

	"github.com/gin-gonic/gin"
	"github.com/user/go-capcut/internal/config"
	"github.com/user/go-capcut/internal/downloader"
	"github.com/user/go-capcut/internal/draft"
	"github.com/user/go-capcut/internal/util"
)

// Handler 处理API请求的处理器
type Handler struct {
	Config     *config.Config
	Cache      draft.Cache
	Downloader downloader.Downloader
}

// NewHandler 创建新的处理器
func NewHandler(cfg *config.Config, cache draft.Cache, downloader downloader.Downloader) *Handler {
	return &Handler{
		Config:     cfg,
		Cache:      cache,
		Downloader: downloader,
	}
}

// Response API响应结构
type Response struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data,omitempty"`
}

// Success 成功响应
func Success(c *gin.Context, data interface{}) {
	c.JSON(http.StatusOK, Response{
		Code: 0,
		Msg:  "success",
		Data: data,
	})
}

// Error 错误响应
func Error(c *gin.Context, code int, msg string) {
	c.JSON(http.StatusOK, Response{
		Code: code,
		Msg:  msg,
	})
}

// CreateDraft 创建草稿
func (h *Handler) CreateDraft(c *gin.Context) {
	// 获取参数
	widthStr := c.DefaultQuery("width", "720")
	heightStr := c.DefaultQuery("height", "1280")
	draftID := c.DefaultQuery("draft_id", "")

	// 转换参数
	width, err := strconv.Atoi(widthStr)
	if err != nil {
		Error(c, 400, "Invalid width parameter")
		return
	}

	height, err := strconv.Atoi(heightStr)
	if err != nil {
		Error(c, 400, "Invalid height parameter")
		return
	}

	// 如果没有提供草稿ID，则生成一个
	if draftID == "" {
		draftID = util.GenerateUUID()
	}

	// 创建新草稿
	draftObj := draft.NewDraft(width, height)
	draftObj.ID = draftID

	// 将草稿存入缓存
	h.Cache.Set(draftID, draftObj)

	// 生成草稿URL
	draftURL := util.GenerateDraftURL(h.Config.DraftDomain, h.Config.PreviewRouter, draftID)

	// 返回响应
	Success(c, gin.H{
		"draft_id":  draftID,
		"draft_url": draftURL,
	})
}

// QueryDraftStatus 查询草稿状态
func (h *Handler) QueryDraftStatus(c *gin.Context) {
	draftID := c.Query("draft_id")
	if draftID == "" {
		Error(c, 400, "Missing draft_id parameter")
		return
	}

	// 从缓存获取草稿
	draftObj, exists := h.Cache.Get(draftID)
	if !exists {
		Error(c, 404, "Draft not found")
		return
	}

	// 返回草稿状态
	Success(c, gin.H{
		"draft_id": draftID,
		"status":   "ready",
		"tracks":   len(draftObj.Tracks),
	})
}

// AddVideo 添加视频
func (h *Handler) AddVideo(c *gin.Context) {
	// 获取参数
	draftID := c.Query("draft_id")
	videoURL := c.Query("video_url")
	startTimeStr := c.DefaultQuery("start_time", "0")
	endTimeStr := c.DefaultQuery("end_time", "-1")
	trackIndexStr := c.DefaultQuery("track_index", "-1")
	volume := c.DefaultQuery("volume", "100")

	if draftID == "" || videoURL == "" {
		Error(c, 400, "Missing required parameters")
		return
	}

	// 从缓存获取草稿
	draftObj, exists := h.Cache.Get(draftID)
	if !exists {
		Error(c, 404, "Draft not found")
		return
	}

	// 转换参数
	startTime, _ := strconv.ParseFloat(startTimeStr, 64)
	endTime, _ := strconv.ParseFloat(endTimeStr, 64)
	trackIndex, _ := strconv.Atoi(trackIndexStr)
	volumeFloat, _ := strconv.ParseFloat(volume, 64)

	// 下载视频
	videoPath, err := h.Downloader.DownloadVideo(videoURL, draftID, util.URLToHash(videoURL))
	if err != nil {
		Error(c, 500, fmt.Sprintf("Failed to download video: %v", err))
		return
	}

	// 添加视频轨道
	trackIndexStr = strconv.Itoa(trackIndex)
	track := draftObj.AddVideoTrack(trackIndexStr)

	// 添加视频片段
	options := map[string]interface{}{
		"volume": volumeFloat / 100.0,
	}
	segment := track.AddVideoSegment(videoPath, startTime, endTime, 0.0, options)

	// 返回响应
	Success(c, gin.H{
		"draft_id":    draftID,
		"track_index": track.Index,
		"segment_id":  segment.ID,
	})
}

// AddAudio 添加音频
func (h *Handler) AddAudio(c *gin.Context) {
	// 获取参数
	draftID := c.Query("draft_id")
	audioURL := c.Query("audio_url")
	startTimeStr := c.DefaultQuery("start_time", "0")
	endTimeStr := c.DefaultQuery("end_time", "-1")
	trackIndexStr := c.DefaultQuery("track_index", "-1")
	volume := c.DefaultQuery("volume", "100")

	if draftID == "" || audioURL == "" {
		Error(c, 400, "Missing required parameters")
		return
	}

	// 从缓存获取草稿
	draftObj, exists := h.Cache.Get(draftID)
	if !exists {
		Error(c, 404, "Draft not found")
		return
	}

	// 转换参数
	startTime, _ := strconv.ParseFloat(startTimeStr, 64)
	endTime, _ := strconv.ParseFloat(endTimeStr, 64)
	trackIndex, _ := strconv.Atoi(trackIndexStr)
	volumeFloat, _ := strconv.ParseFloat(volume, 64)

	// 下载音频
	audioPath, err := h.Downloader.DownloadAudio(audioURL, draftID, util.URLToHash(audioURL))
	if err != nil {
		Error(c, 500, fmt.Sprintf("Failed to download audio: %v", err))
		return
	}

	// 添加音频轨道
	trackIndexStr = strconv.Itoa(trackIndex)
	track := draftObj.AddAudioTrack(trackIndexStr)

	// 添加音频片段
	options := map[string]interface{}{
		"volume": volumeFloat / 100.0,
	}
	segment := track.AddAudioSegment(audioPath, startTime, endTime, 0.0, options)

	// 返回响应
	Success(c, gin.H{
		"draft_id":    draftID,
		"track_index": track.Index,
		"segment_id":  segment.ID,
	})
}

// AddText 添加文本
func (h *Handler) AddText(c *gin.Context) {
	// 获取参数
	draftID := c.Query("draft_id")
	text := c.Query("text")
	colorStr := c.DefaultQuery("color", "#FFFFFF")
	fontSize := c.DefaultQuery("font_size", "36")
	durationStr := c.DefaultQuery("duration", "5")
	trackIndexStr := c.DefaultQuery("track_index", "-1")

	if draftID == "" || text == "" {
		Error(c, 400, "Missing required parameters")
		return
	}

	// 从缓存获取草稿
	draftObj, exists := h.Cache.Get(draftID)
	if !exists {
		Error(c, 404, "Draft not found")
		return
	}

	// 转换参数
	duration, _ := strconv.ParseFloat(durationStr, 64)
	trackIndex, _ := strconv.Atoi(trackIndexStr)
	fontSizeInt, _ := strconv.Atoi(fontSize)

	// 添加文本轨道
	trackIndexStr = strconv.Itoa(trackIndex)
	track := draftObj.AddTextTrack(trackIndexStr)

	// 添加文本片段
	options := map[string]interface{}{
		"font_color": colorStr,
		"font_size":  float64(fontSizeInt),
	}
	segment := track.AddTextSegment(text, 0.0, duration, options)

	// 返回响应
	Success(c, gin.H{
		"draft_id":    draftID,
		"track_index": track.Index,
		"segment_id":  segment.ID,
	})
}

// AddImage 添加图片
func (h *Handler) AddImage(c *gin.Context) {
	// 获取参数
	draftID := c.Query("draft_id")
	imageURL := c.Query("image_url")
	durationStr := c.DefaultQuery("duration", "5")
	trackIndexStr := c.DefaultQuery("track_index", "-1")

	if draftID == "" || imageURL == "" {
		Error(c, 400, "Missing required parameters")
		return
	}

	// 从缓存获取草稿
	draftObj, exists := h.Cache.Get(draftID)
	if !exists {
		Error(c, 404, "Draft not found")
		return
	}

	// 转换参数
	duration, _ := strconv.ParseFloat(durationStr, 64)
	trackIndex, _ := strconv.Atoi(trackIndexStr)

	// 下载图片
	imagePath, err := h.Downloader.DownloadImage(imageURL, draftID, util.URLToHash(imageURL))
	if err != nil {
		Error(c, 500, fmt.Sprintf("Failed to download image: %v", err))
		return
	}

	// 添加图片轨道
	trackIndexStr = strconv.Itoa(trackIndex)
	track := draftObj.AddImageTrack(trackIndexStr)

	// 添加图片片段
	options := map[string]interface{}{}
	segment := track.AddImageSegment(imagePath, 0.0, duration, options)

	// 返回响应
	Success(c, gin.H{
		"draft_id":    draftID,
		"track_index": track.Index,
		"segment_id":  segment.ID,
	})
}

// AddEffect 添加特效
func (h *Handler) AddEffect(c *gin.Context) {
	// 获取参数
	draftID := c.Query("draft_id")
	trackIndexStr := c.Query("track_index")
	segmentID := c.Query("segment_id")
	effectType := c.Query("effect_type")
	effectName := c.Query("effect_name")
	startTimeStr := c.DefaultQuery("start_time", "0")
	endTimeStr := c.DefaultQuery("end_time", "-1")

	if draftID == "" || trackIndexStr == "" || segmentID == "" || effectType == "" || effectName == "" {
		Error(c, 400, "Missing required parameters")
		return
	}

	// 从缓存获取草稿
	draftObj, exists := h.Cache.Get(draftID)
	if !exists {
		Error(c, 404, "Draft not found")
		return
	}

	// 转换参数
	trackIndex, _ := strconv.Atoi(trackIndexStr)
	startTime, _ := strconv.ParseFloat(startTimeStr, 64)
	endTime, _ := strconv.ParseFloat(endTimeStr, 64)

	// 查找轨道
	var track *draft.Track
	trackIndexFloat := float64(trackIndex)
	for i := range draftObj.Tracks {
		if draftObj.Tracks[i].Index == trackIndexFloat {
			track = &draftObj.Tracks[i]
			break
		}
	}

	if track == nil {
		Error(c, 404, "Track not found")
		return
	}

	// 查找片段
	var segment *draft.Segment
	for i := range track.Segments {
		if track.Segments[i].ID == segmentID {
			segment = &track.Segments[i]
			break
		}
	}

	if segment == nil {
		Error(c, 404, "Segment not found")
		return
	}

	// 添加特效
	params := map[string]interface{}{
		"name":       effectName,
		"start_time": startTime,
		"end_time":   endTime,
	}
	effect := segment.AddEffect(effectType, params)

	// 返回响应
	Success(c, gin.H{
		"draft_id":   draftID,
		"effect_id":  effect.ID,
		"segment_id": segment.ID,
	})
}

// SaveDraft 保存草稿
func (h *Handler) SaveDraft(c *gin.Context) {
	h.SaveDraftHandler(c)
}
